package com.mou.aiagent.agent.model;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.mou.aiagent.tools.TerminateTool;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.ToolResponseMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.tool.ToolCallingManager;
import org.springframework.ai.model.tool.ToolExecutionResult;
import org.springframework.ai.tool.ToolCallback;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 处理工具调用代理
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Slf4j
public class ToolCallAgent extends ReActAgent{
    // 可用的工具
    private ToolCallback[] availableTools;
    // 保存调用工具响应信息（要调用的那些工具）
    private ChatResponse toolCallChatResponse;
    // sring Ai 工具调用管理
    private final ToolCallingManager toolCallbackManager;
    // 禁用 Spring AI 的工具调用 ，使用自己控制工具调用
    private final ChatOptions chatOptions;
    // 外部传入调用工具
    public  ToolCallAgent(ToolCallback[] availTools){
        super();
        this.availableTools=availTools;
        this.toolCallbackManager = ToolCallingManager.builder()
                .build();

        // 创建一个DashScopeChatOptions对象，并设置代理工具调用为true
        this.chatOptions= DashScopeChatOptions.builder()
                .withProxyToolCalls(true)
                .build();
    }
    @Override
    public boolean think() {
        try {
            // 1思考
            // 1.1校验提示词，拼接用户提示词 getNextStepPrompt() 下一步的提示词
            if (StrUtil.isNotBlank(getNextStepPrompt())){
                // 1.2 把提示词发送给AI
                UserMessage userMessage = new UserMessage(getNextStepPrompt());
                 // 1.3 添加提示词带集合中
               getMessageList().add(userMessage);
               // 1.4 从集合中获取到提示词
                List<Message> messagesList = getMessageList();
                // 定义提示词发送给AI
                Prompt prompt = new Prompt(messagesList, chatOptions);
                // 1.5 发送给AI
                ChatResponse chatResponse = getChatClient()
                        .prompt(prompt)
                        .system(getSystemPrompt())
                        .tools(availableTools)
                        .call()
                        .chatResponse();
                // 1.6 保存工具调用响应信息 到 toolCallChatResponse 等一下act()方法使用
                this.toolCallChatResponse=chatResponse;
            }
            // 2 从toolCallChatResponse 获取工具调用，解析结果  output助手消息

            AssistantMessage output = toolCallChatResponse.getResult().getOutput();
            // 2.1 获取要调用的工具列表
            List<AssistantMessage.ToolCall> toolCallsList = output.getToolCalls();
            // 2.2 输出提示信息
            String toolCallResult = output.getText();
            log.info(getName()+"谁的思考" +toolCallResult);
            log.info(getName()+"选择了" +toolCallsList.size()+"个工具");
            // 2.3 输出工具调用信息
            String collect = toolCallsList.stream()
                    .map(toolCall -> String.format("工具名称：%s，工具参数：%s", toolCall.name(), toolCall.arguments()))
                    .collect(Collectors.joining("\n"));
            log.info(getName()+"工具调用信息" +collect);
            // 3判断是否要调用工具 lase 不需要调用
            if(toolCallsList.isEmpty()){
                // 添加消息 记助手消息
                getMessageList().add(output);
                return false;
            }else {
                // 需要调用工具时，无需记录助手消息，因为工具会自动记录
                return true;
            }
        } catch (Exception e) {
            log.error(getName()+"思考异常",e);
            // 给AI 新增错误信息
            AssistantMessage assistantMessage = new AssistantMessage(e.getMessage()+"处理错误");
            getMessageList().add(assistantMessage);
            return false;
        }
    }

    /**
     * 执行调用工具
     * @return 执行结果
     */
    @Override
    public String act() {
        if (!toolCallChatResponse.hasToolCalls()) {
            return "没有要调用的工具";
        }
        // 调用工具
        Prompt prompt = new Prompt(getMessageList(), this.chatOptions);
        ToolExecutionResult toolExecutionResult = toolCallbackManager.executeToolCalls(prompt, toolCallChatResponse);
         // 记录消息上下文到集合中
         getMessageList().addAll(toolExecutionResult.conversationHistory());
         // 获取工具调用结果 拿到最新的消息
       ToolResponseMessage toolResponse= (ToolResponseMessage) CollUtil.getLast(toolExecutionResult.conversationHistory());
         // 判断是否调用了结束工具
        boolean terminateTool = toolResponse.getResponses().stream()
                .anyMatch(respone -> respone.name().equals("TerminateTool"));
        // 判断是否调用了结束工具，调用了就更改云心状态
        if (terminateTool) {
            // 更改状态 为完成
            setState(AgentState.FINISHED);
        }

       // 获取工具调用结果
        String results = toolResponse.getResponses().stream()
                // 映射为字符串
                .map(response -> "工具" + response.name() + "返回结果" + response.responseData())
                .collect(Collectors.joining("\n"));
        log.info(getName()+"工具调用结果" +results);
        return null;
    }
}
